home *** CD-ROM | disk | FTP | other *** search
/ Creative Computers / Creative Computers CD-ROM, Volume 1 (Legendary Design Technologies, Inc.)(1994).iso / shareware / fractals / mandelsquare / mandelsquare-1.06.lha / ILBM.c < prev    next >
C/C++ Source or Header  |  1992-12-20  |  18KB  |  836 lines

  1. /*
  2. **    MandelSquare - AmigaDOS 2.0/3.0 Mandelbrot set explorer
  3. **
  4. **    ILBM.c, Routines to load and save IFF-ILBM files
  5. **
  6. **    Copyright © 1991-1992 by Olaf `Olsen' Barthel
  7. **        All Rights Reserved
  8. */
  9.  
  10.     /* A picture handle. */
  11.  
  12. struct PictureInfo
  13. {
  14.     BitMapHeader        BitMapHeader;
  15.     MandelHeader        MandelHeader;
  16.     struct Palette *    Palette;    
  17.     ULONG            ViewModes;
  18.     struct BitMap *        BitMap;
  19. };
  20.  
  21.     /* Global flag. */
  22.  
  23. extern BYTE        Is39;
  24.  
  25.     /* In Packer.c */
  26.  
  27. extern LONG __regargs    PackRow(BYTE **pSource,BYTE *dest,LONG rowSize);
  28. extern VOID __regargs    UnPackRow(BYTE **pSource,BYTE **pDest,WORD dstBytes);
  29.  
  30.     /* In Palette.c */
  31.  
  32. extern VOID        FreePalette(struct Palette *Palette);
  33. extern struct Palette *    AllocPalette(LONG NumColours,BYTE TrueColour);
  34. extern struct Palette *    GetPalette(struct Screen *Screen,struct Palette *Palette);
  35. extern VOID        LoadPalette(struct Screen *Screen,struct Palette *Palette,LONG NumColours);
  36. extern LONG        GetPaletteSize(struct Palette *Palette);
  37. extern BYTE        GetPaletteTriplet(struct Palette *Palette,UBYTE *Triplet,LONG Index);
  38. extern BYTE        SetPaletteTriplet(struct Palette *Palette,UBYTE R,UBYTE G,UBYTE B,LONG Index);
  39. extern ULONG        GetPaletteEntry(struct Palette *Palette,LONG Index);
  40. extern BYTE        SetPaletteEntry(struct Palette *Palette,ULONG Entry,LONG Index);
  41.  
  42.     /* Local, static routines. */
  43.  
  44. STATIC VOID __regargs    GetBody(struct BitMap *BitMap,APTR Body);
  45. STATIC BYTE __regargs    GetColourMap(struct PictureInfo *Info,UBYTE *Palette,LONG Size);
  46. STATIC BYTE __regargs    PutMandel(struct IFFHandle *Handle,MandelHeader *Mandel);
  47. STATIC BYTE __regargs    PutCRange(struct IFFHandle *Handle,CRange *Range);
  48.  
  49.     /* Exported routines. */
  50.  
  51. VOID            FreeCustomBitMap(struct BitMap *BitMap,BYTE Standard);
  52. struct BitMap *        AllocCustomBitMap(UWORD Depth,UWORD Width,UWORD Height,BYTE Standard);
  53. BYTE            PutBitMap(struct IFFHandle *Handle,struct BitMap *BitMap);
  54. BYTE            PutViewModes(struct IFFHandle *Handle,struct ViewPort *VPort);
  55. BYTE            PutColourMap(struct IFFHandle *Handle,struct ViewPort *VPort);
  56. BYTE            PutBitMapHeader(struct IFFHandle *Handle,struct Screen *Screen);
  57. VOID            FreePicture(struct PictureInfo *Info);
  58. struct PictureInfo *    LoadPicture(STRPTR Name);
  59. BYTE            SavePicture(STRPTR Name,struct Screen *Screen,MandelHeader *Mandel);
  60.  
  61.     /* GetBody(struct BitMap *BitMap,APTR Body):
  62.      *
  63.      *    Unpack compressed data.
  64.      */
  65.  
  66. STATIC VOID __regargs
  67. GetBody(struct BitMap *BitMap,APTR Body)
  68. {
  69.     PLANEPTR     Planes[8];
  70.     BYTE        *Source;
  71.     LONG         i,j;
  72.  
  73.         /* Get the source data pointer, we will modify it. */
  74.  
  75.     Source = (BYTE *)Body;
  76.  
  77.         /* Copy the bitplane pointers. */
  78.  
  79.     for(i = 0 ; i < BitMap -> Depth ; i++)
  80.         Planes[i] = BitMap -> Planes[i];
  81.  
  82.         /* CmpByteRun decompression. */
  83.  
  84.     for(i = 0 ; i < BitMap -> Rows ; i++)
  85.     {
  86.         for(j = 0 ; j < BitMap -> Depth ; j++)
  87.             UnPackRow(&Source,&Planes[j],BitMap -> BytesPerRow);
  88.     }
  89. }
  90.  
  91.     /* GetColourMap(struct PictureInfo *Info,UBYTE *Palette,LONG Size):
  92.      *
  93.      *    Fill in colour map information.
  94.      */
  95.  
  96. STATIC BYTE __regargs
  97. GetColourMap(struct PictureInfo *Info,UBYTE *Palette,LONG Size)
  98. {
  99.         /* Get the number of colours. */
  100.  
  101.     LONG NumColours = Size / 3;
  102.  
  103.         /* Allocate palette information. */
  104.  
  105.     if(Info -> Palette = AllocPalette(NumColours,NumColours == 256))
  106.     {
  107.         UWORD    R,G,B;
  108.         LONG    i;
  109.  
  110.             /* Set the 8 bit triplets. */
  111.  
  112.         if(NumColours == 256)
  113.         {
  114.             for(i = 0 ; i < NumColours ; i++)
  115.             {
  116.                 R = *Palette++;
  117.                 G = *Palette++;
  118.                 B = *Palette++;
  119.  
  120.                 SetPaletteTriplet(Info -> Palette,R,G,B,i);
  121.             }
  122.         }
  123.         else
  124.         {
  125.                 /* Set the 4 bit triplets. */
  126.  
  127.             for(i = 0 ; i < NumColours ; i++)
  128.             {
  129.                 R = ((*Palette++) >> 4) & 0xF;
  130.                 G = ((*Palette++) >> 4) & 0xF;
  131.                 B = ((*Palette++) >> 4) & 0xF;
  132.  
  133.                 SetPaletteTriplet(Info -> Palette,R,G,B,i);
  134.             }
  135.         }
  136.  
  137.         return(TRUE);
  138.     }
  139.     else
  140.         return(FALSE);
  141. }
  142.  
  143.     /* PutMandel(struct IFFHandle *Handle,MandelHeader *Mandel):
  144.      *
  145.      *    Save the mandelbrot information chunk.
  146.      */
  147.  
  148. STATIC BYTE __regargs
  149. PutMandel(struct IFFHandle *Handle,MandelHeader *Mandel)
  150. {
  151.     if(!PushChunk(Handle,0,ID_MAND,sizeof(MandelHeader)))
  152.     {
  153.         if(WriteChunkRecords(Handle,Mandel,sizeof(MandelHeader),1) == 1)
  154.         {
  155.             if(!PopChunk(Handle))
  156.                 return(TRUE);
  157.         }
  158.     }
  159.  
  160.     return(FALSE);
  161. }
  162.  
  163.     /* PutCRange(struct IFFHandle *Handle,CRange *Range):
  164.      *
  165.      *    Save the colour cycling chunk.
  166.      */
  167.  
  168. STATIC BYTE __regargs
  169. PutCRange(struct IFFHandle *Handle,CRange *Range)
  170. {
  171.     if(!PushChunk(Handle,0,ID_CRNG,sizeof(CRange)))
  172.     {
  173.         if(WriteChunkRecords(Handle,Range,sizeof(CRange),1) == 1)
  174.         {
  175.             if(!PopChunk(Handle))
  176.                 return(TRUE);
  177.         }
  178.     }
  179.  
  180.     return(FALSE);
  181. }
  182.  
  183.     /* FreeCustomBitMap(struct BitMap *BitMap,BYTE Standard):
  184.      *
  185.      *    Free bitmap memory.
  186.      */
  187.  
  188. VOID
  189. FreeCustomBitMap(struct BitMap *BitMap,BYTE Standard)
  190. {
  191.     if(Is39)
  192.         FreeBitMap(BitMap);
  193.     else
  194.     {
  195.         if(BitMap)
  196.         {
  197.             WORD i;
  198.  
  199.             for(i = 0 ; i < BitMap -> Depth ; i++)
  200.             {
  201.                 if(BitMap -> Planes[i])
  202.                     FreeVec(BitMap -> Planes[i]);
  203.             }
  204.  
  205.             FreeVec(BitMap);
  206.         }
  207.     }
  208. }
  209.  
  210.     /* AllocCustomBitMap(UWORD Depth,UWORD Width,UWORD Height,BYTE Standard):
  211.      *
  212.      *    Allocate bitmap memory.
  213.      */
  214.  
  215. struct BitMap *
  216. AllocCustomBitMap(UWORD Depth,UWORD Width,UWORD Height,BYTE Standard)
  217. {
  218.     if(Is39)
  219.     {
  220.         extern struct Screen *Screen;
  221.  
  222.             /* Note: `Standard' assumes that a BitMap with properly
  223.              *       set line modulo values (i.e. no chunky, interleaved
  224.              *       or whatever layout possible) will be allocated and
  225.              *       returned. This BitMap will never be used for
  226.              *       screen display but rather as a temporary buffer
  227.              *       for image compression.
  228.              */
  229.  
  230.         if(Standard)
  231.             return(AllocBitMap(Width,Height,Depth,BMF_CLEAR,NULL));
  232.         else
  233.             return(AllocBitMap(Width,Height,Depth,BMF_CLEAR | BMF_DISPLAYABLE,Screen -> RastPort . BitMap));
  234.     }
  235.     else
  236.     {
  237.         struct BitMap *BitMap;
  238.  
  239.             /* Allocate the bitmap body. */
  240.  
  241.         if(BitMap = (struct BitMap *)AllocVec(sizeof(struct BitMap),MEMF_ANY | MEMF_CLEAR))
  242.         {
  243.             BYTE    Success = TRUE;
  244.             LONG    PlaneSize,
  245.                 i;
  246.  
  247.                 /* Initialize the bitmap. */
  248.  
  249.             InitBitMap(BitMap,Depth,Width,Height);
  250.  
  251.                 /* Get the plane size. */
  252.  
  253.             PlaneSize = BitMap -> BytesPerRow * BitMap -> Rows;
  254.  
  255.                 /* Allocate the single bitplanes. */
  256.  
  257.             for(i = 0 ; Success && i < Depth ; i++)
  258.             {
  259.                 if(!(BitMap -> Planes[i] = (PLANEPTR)AllocVec(PlaneSize,MEMF_CHIP | MEMF_CLEAR)))
  260.                     Success = FALSE;
  261.             }
  262.  
  263.                 /* Return the result. */
  264.  
  265.             if(Success)
  266.                 return(BitMap);
  267.             else
  268.                 FreeCustomBitMap(BitMap,Standard);
  269.         }
  270.     }
  271.  
  272.     return(NULL);
  273. }
  274.  
  275.     /* PutBitMap(struct IFFHandle *Handle,struct BitMap *BitMap):
  276.      *
  277.      *    Save a bitmap to disk.
  278.      */
  279.  
  280. BYTE
  281. PutBitMap(struct IFFHandle *Handle,struct BitMap *BitMap)
  282. {
  283.     PLANEPTR    *Planes;
  284.     BYTE        *PackBuffer,
  285.              Success = FALSE;
  286.     LONG         PackedBytes,
  287.              i,j;
  288.  
  289.         /* Allocate the bitplane information. */
  290.  
  291.     if(Planes = (PLANEPTR *)AllocVec(BitMap -> Depth * sizeof(PLANEPTR *),MEMF_ANY | MEMF_CLEAR))
  292.     {
  293.             /* Allocate the compression buffer. */
  294.  
  295.         if(PackBuffer = (BYTE *)AllocVec(BitMap -> BytesPerRow * 2,MEMF_ANY))
  296.         {
  297.                 /* Copy the planes over. */
  298.  
  299.             for(i = 0 ; i < BitMap -> Depth ; i++)
  300.                 Planes[i] = BitMap -> Planes[i];
  301.  
  302.             if(!PushChunk(Handle,0,ID_BODY,IFFSIZE_UNKNOWN))
  303.             {
  304.                 Success = TRUE;
  305.  
  306.                     /* Run down the rows. */
  307.  
  308.                 for(i = 0 ; Success && i < BitMap -> Rows ; i++)
  309.                 {
  310.                     for(j = 0 ; Success && j < BitMap -> Depth ; j++)
  311.                     {
  312.                             /* Pack the data. */
  313.  
  314.                         PackedBytes = PackRow(&Planes[j],PackBuffer,BitMap -> BytesPerRow);
  315.  
  316.                             /* Write it to disk. */
  317.  
  318.                         if(WriteChunkRecords(Handle,PackBuffer,PackedBytes,1) != 1)
  319.                             Success = FALSE;
  320.                     }
  321.                 }
  322.  
  323.                 if(PopChunk(Handle))
  324.                     Success = FALSE;
  325.             }
  326.  
  327.             FreeVec(PackBuffer);
  328.         }
  329.  
  330.         FreeVec(Planes);
  331.     }
  332.  
  333.     return(Success);
  334. }
  335.  
  336.     /* PutViewModes(struct IFFHandle *Handle,struct ViewPort *VPort):
  337.      *
  338.      *    Save the display modes to disk.
  339.      */
  340.  
  341. BYTE
  342. PutViewModes(struct IFFHandle *Handle,struct ViewPort *VPort)
  343. {
  344.     ULONG ViewModes = GetVPModeID(VPort);
  345.  
  346.     if(!PushChunk(Handle,0,ID_CAMG,sizeof(ULONG)))
  347.     {
  348.         if(WriteChunkRecords(Handle,&ViewModes,sizeof(ULONG),1) == 1)
  349.         {
  350.             if(!PopChunk(Handle))
  351.                 return(TRUE);
  352.         }
  353.     }
  354.  
  355.     return(FALSE);
  356. }
  357.  
  358.     /* PutColourMap(struct IFFHandle *Handle,struct ViewPort *VPort):
  359.      *
  360.      *    Save the colour map to disk.
  361.      */
  362.  
  363. BYTE
  364. PutColourMap(struct IFFHandle *Handle,struct ViewPort *VPort)
  365. {
  366.     ColorRegister     C